package com.tanhua.app.Service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanhua.app.exception.BusinessException;
import com.tanhua.app.interceptor.UserHolder;
import com.tanhua.commons.utils.Constants;
import com.tanhua.config.template.HuanXinTemplate;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.pojo.Question;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class TanhuaService {
    @DubboReference
    private RecommendUserApi recommendUserApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private QuestionApi questionApi;
    @DubboReference
    private UserLikeApi userLikeApi;
    @DubboReference
    private UserLocationApi userLocationApi;
    @DubboReference
    private VisitorsApi visitorsApi;
    @DubboReference
    private FriendApi friendApi;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MessagesService messagesService;

    //    今日佳人
    public TodayBest todayBest() {
        Long userId = UserHolder.getUserId();
        RecommendUser recommendUser = recommendUserApi.findWithMaxScore(userId);
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        return vo;
    }

    //    推荐朋友
    public PageResult recommendation(RecommendUserDto dto) {
        Long userId = UserHolder.getUserId();
        List<RecommendUser> recommendUserList = recommendUserApi.queryRecommendUserList(userId);
        if(recommendUserList==null || recommendUserList.isEmpty()){
            return new PageResult(dto.getPage(),dto.getPagesize(),0,null);
        }
//        List<Long> ids = CollUtil.getFieldValues(recommendUserList, "userId", Long.class);
        List<Long> ids = recommendUserList.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        Page<UserInfo> pages = userInfoApi.findByIds(ids,dto);
        Map<Long, RecommendUser> userMap = recommendUserList.stream().collect(Collectors.toMap(RecommendUser::getUserId, Function.identity()));
        List<TodayBest> list = pages.getRecords().stream().map(item -> {
            RecommendUser recommendUser = userMap.get(item.getId());
            return TodayBest.init(item, recommendUser);
        }).collect(Collectors.toList());
        return new PageResult(dto.getPage(),dto.getPagesize(), (int) pages.getTotal(),list);
    }

    //    查看佳人信息
    public TodayBest personalInfo(Long userId) {
        UserInfo userInfo = userInfoApi.findById(userId);
        RecommendUser recommendUser = recommendUserApi.queryByUserId(userId,UserHolder.getUserId());

        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setDate(System.currentTimeMillis());
        visitors.setFrom("首页");
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);

        return TodayBest.init(userInfo, recommendUser);
    }

    //    查询陌生人问题
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        return question==null?"你喜欢java编程吗？":question.getTxt();
    }

    //    回复陌生人问题
    public void replyQuestions(Long userId, String reply) {
        Long id = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.findById(id);
        Map map = new HashMap();
        map.put("userId",id);
        map.put("huanXinId", Constants.HX_USER_PREFIX+id);
        map.put("nickname",userInfo.getNickname());
        map.put("strangerQuestion",strangerQuestions(userId));
        map.put("reply",reply);
        String message = JSON.toJSONString(map);
        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    @Value("${tanhua.default.recommend.users}")
    private List<Long> userIds;

    //    探花-左滑右滑
    public List<TodayBest> queryCardsList() {
        Long userId = UserHolder.getUserId();
        List<RecommendUser> recommendUsers = recommendUserApi.queryCardsUserList(userId,10);
        if(CollUtil.isEmpty(recommendUsers)){
            recommendUsers = new ArrayList<>();
            for (Long id : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(id);
                recommendUser.setToUserId(userId);
                recommendUser.setScore(RandomUtil.randomDouble(60,90));
                recommendUsers.add(recommendUser);
            }
        }
        List<Long> ids = recommendUsers.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoApi.findByUserIds(ids);
        Map<Long, UserInfo> map = userInfos.stream().collect(Collectors.toMap(UserInfo::getId, Function.identity()));
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUsers) {
            UserInfo userInfo = map.get(recommendUser.getUserId());
            if (userInfo != null) {
                TodayBest vo = TodayBest.init(userInfo, recommendUser);
                vos.add(vo);
            }
        }
        return vos;
    }

    //    探花-喜欢
    public void likeUser(Long likeUserId) {
        Long userId = UserHolder.getUserId();
        Boolean save = userLikeApi.saveOrUpdate(likeUserId,userId,true);
        if (save) {
            messagesService.contacts(likeUserId);
        }
//        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY+userId,likeUserId.toString());
//        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + userId,likeUserId.toString());
//        if(redisTemplate.opsForSet().isMember(Constants.USER_LIKE_KEY +likeUserId,userId.toString())){
//            messagesService.contacts(likeUserId);
//        }
    }

    //    探花-不喜欢
    public void notLikeUser(Long notLikeUserId) {
        Long userId = UserHolder.getUserId();
        Boolean aBoolean = userLikeApi.saveOrUpdate(notLikeUserId, userId, false);
        if (friendApi.isLike(userId,notLikeUserId)) {
            if (!aBoolean) {
                messagesService.removeContacts(notLikeUserId);
            }
        }
//        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + userId,notLikeUserId.toString());
//        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + userId,notLikeUserId.toString());
//        if(redisTemplate.opsForSet().isMember(Constants.USER_NOT_LIKE_KEY+notLikeUserId,userId.toString())){
//            messagesService.removeContacts(notLikeUserId);
//        }
    }

    //    搜附近
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        Long userId = UserHolder.getUserId();
        List<Long> userIds = userLocationApi.queryNearUser(userId,Double.parseDouble(distance));
        if(CollUtil.isEmpty(userIds)){
            return new ArrayList<>();
        }
        List<UserInfo> userInfos = userInfoApi.findByUserIds(userIds,gender);
        List<NearUserVo> vos = new ArrayList<>();
        for (UserInfo userInfo : userInfos) {
            if(userInfo.getId().longValue()==userId.longValue()){
                continue;
            }
            NearUserVo vo = NearUserVo.init(userInfo);
            vos.add(vo);
        }
        return vos;
    }
}




